package org.thss.petri.gef.ui;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.gef.palette.CombinedTemplateCreationEntry;
import org.eclipse.gef.palette.ConnectionCreationToolEntry;
import org.eclipse.gef.palette.MarqueeToolEntry;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteEntry;
import org.eclipse.gef.palette.PaletteGroup;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.SelectionToolEntry;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.thss.petri.model.Arc;
import org.thss.petri.model.PetriFactory;
import org.thss.petri.model.Place;
import org.thss.petri.model.Token;
import org.thss.petri.model.Transition;
import org.thss.petri.gef.PetriNetActivator;

public class PetriNetPaletteFactory {
	
	 /**
	  * Add controls for place, token, transaction, and arc
	  * @return
	  */
	 public static PaletteRoot createPalette() 
	 {
	        PaletteRoot flowPalette = new PaletteRoot();
	        flowPalette.addAll(createCategories(flowPalette));
	        return flowPalette;
	 }
	 
	 private static List<PaletteEntry> createCategories(PaletteRoot root) {
		 List<PaletteEntry> categories = new ArrayList<PaletteEntry>();
		 //Control Group
	     categories.add(createControlGroup(root));
		 //PetriNet Component
	     categories.add(createPetriNetComponentGroup());
	     //PetriNet Connection
	     categories.add(createPetriNetConnectionGroup());
	     
		 return categories;
	 }
	 
	 /**
	  * Control Group
	  * @param root
	  * @return
	  */
    private static PaletteContainer createControlGroup(PaletteRoot root) {
        PaletteGroup controlGroup = new PaletteGroup("Control Group");

        List<PaletteEntry> entries = new ArrayList<PaletteEntry>();

        ToolEntry tool = new SelectionToolEntry();
        entries.add(tool);
        root.setDefaultEntry(tool);

        tool = new MarqueeToolEntry();
        entries.add(tool);
        
        controlGroup.addAll(entries);
        return controlGroup;
    }

    /**
     * PetriNet Component Group
     * @return
     */
    private static PaletteContainer createPetriNetComponentGroup() {
    	PaletteDrawer drawer = new PaletteDrawer("Component", null);
    	List<PaletteEntry> entries = new ArrayList<PaletteEntry>();
    	
    	//Place
    	CombinedTemplateCreationEntry place = new CombinedTemplateCreationEntry(
    			"Place",
    			"Add a place node",
    			new CreationFactory() {
					public Object getNewObject() {
						return PetriFactory.eINSTANCE.createPlace();
					}
					public Object getObjectType() {
						return Place.class;
					}},
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif")),
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif"))
    			);
    	entries.add(place);
    	
    	
    	//Transition
    	CombinedTemplateCreationEntry transition = new CombinedTemplateCreationEntry(
    			"Transition",
    			"Add a transition node",
    			new CreationFactory() {
					public Object getNewObject() {
						return PetriFactory.eINSTANCE.createTransition();
					}
					public Object getObjectType() {
						return Transition.class;
					}},
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif")),
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif"))
    			);
    	entries.add(transition);
    	
    	//Token
    	CombinedTemplateCreationEntry token = new CombinedTemplateCreationEntry(
    			"Token",
    			"Add a token node",
    			new CreationFactory() {
					public Object getNewObject() {
						return PetriFactory.eINSTANCE.createToken();
					}
					public Object getObjectType() {
						return Token.class;
					}},
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif")),
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif"))
    			);
    	entries.add(token);
    	
    	drawer.addAll(entries);
    	return drawer;
    }

    
    /**
     * PetriNet Connection Group
     * @return
     */
    private static PaletteContainer createPetriNetConnectionGroup() {
    	PaletteDrawer drawer = new PaletteDrawer("Connection", null);
    	List<PaletteEntry> entries = new ArrayList<PaletteEntry>();
    	
    	ConnectionCreationToolEntry arc = new ConnectionCreationToolEntry(
    			"Arc",
    			"Add an arc",
    			new CreationFactory() {
					public Object getNewObject() {
						return PetriFactory.eINSTANCE.createArc();
					}
					public Object getObjectType() {
						return Arc.class;
					}},
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif")),
					ImageDescriptor.createFromURL(PetriNetActivator.getDefault().getBundle().getEntry("icons/sample.gif"))
    			);
    	entries.add(arc);
    	
    	drawer.addAll(entries);
    	return drawer;
    }
}
